#ifndef __TCP_SERVER_HPP__
#define __TCP_SERVER_HPP__
#include <iostream>
#include <string>
#include <string.h>
#include <pthread.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "MyPthread/Log.hpp"
#include "MyPthread/ThreadPool.hpp"
#include "InetAddr.hpp"
#include "Common.hpp"
#include "Socket.hpp"


namespace TcpServerModule
{
    using namespace LogModule;
    using namespace ThreadModule;
    using namespace SocketModule;

    const static int gsockfd = -1;
    // const static std::string gdefaultip = "127.0.0.1"; // 表示本地主机

    using task_t = std::function<void()>;
    using tcp_handler_t = std::function<bool(SockPtr, InetAddr)>;
    class TcpServer;

    struct ThreadData
    {
        TcpServer *_this;
        int _sockfd;
        InetAddr _client;
        ThreadData(TcpServer *t, int sockfd, InetAddr client)
            : _this(t), _sockfd(sockfd), _client(client)
        {
        }
    };
    // 是它只负责进行IO，流式的IO，不对协议进行任何处理
    class TcpServer
    {
    public:
        TcpServer(uint16_t server_port = gserver_port)
            : _listen_sock_ptr(std::make_shared<TcpSocket>(server_port)), _server(server_port), _isrunning(false)
        {
            // LOG(LogLevel::DEBUG) << "TcpServer::TcpServer()";
            // 1. 创建监听socket
            _listen_sock_ptr->BuildTcpSocketMethod(server_port);
            // LOG(LogLevel::DEBUG) << "TcpServer::TcpServer() _listen_sock_ptr: " << _listen_sock_ptr;
        }
        ~TcpServer()
        {
            _listen_sock_ptr->Close();
        }

        void RegisterSerive(tcp_handler_t handler)
        {
            _handler = handler;
        }

        void Loop()
        {
            _isrunning = true;
            while (_isrunning)
            {
                // LOG(LogLevel::DEBUG) << "TcpServer::Loop()";
                InetAddr client;
                // LOG(LogLevel::DEBUG) << "TcpServer::Loop() _listen_sock: " << _listen_sock_ptr->Fd();
                // 3.获取连接
                SockPtr new_sock = _listen_sock_ptr->Accepter(&client);
                // LOG(LogLevel::DEBUG) << "TcpServer::Loop() new_sock: " << new_sock;
                int sockfd = new_sock->Fd();
                if (sockfd < 0)
                {
                    LOG(LogLevel::WARNING) << "accept error: " << strerror(errno);
                    LOG(LogLevel::WARNING) << "_listen_sockfd: " << _listen_sock_ptr;

                    continue;
                }
                pid_t id = ::fork();
                if(id == 0)
                {
                    if(::fork() == 0)
                    {
                        _listen_sock_ptr->Close();
                        LOG(LogLevel::DEBUG) << "TcpServer::Loop() child process";
                        // 4.交给上层处理
                        _handler(new_sock, client);
                    }
                    ::exit(0);
                }
                new_sock->Close();
                waitpid(id, nullptr, 0);
                
            }
            _isrunning = false;
        }

    private:
        std::shared_ptr<Socket> _listen_sock_ptr;
        InetAddr _server;
        // InetAddr _client;
        bool _isrunning; // 服务器运行状态

        // 业务
        tcp_handler_t _handler;
    };
}
#endif